package evaluation;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import customization.Constants;
import dataguide.PathPair;

public class PrecisionRecall {

	static ArrayList<GoldSetPairs> goldSet; // = new ArrayList<GoldSetPairs>();
	static float precision;
	static float recall;

	public PrecisionRecall() {
		// goldSet = new ArrayList<GoldSetPairs>();
	}

	public void parseGoldSetFile(String filepath) {
		try (BufferedReader br = new BufferedReader(new FileReader(filepath))) {

			String sCurrentLine;
			while ((sCurrentLine = br.readLine()) != null) {
				String[] line = sCurrentLine.split(Constants.separatorSpace);
				GoldSetPairs pair = new GoldSetPairs(line[0], line[1]);
				goldSet.add(pair);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void parseResultsFile(String filepath) {
		try (BufferedReader br = new BufferedReader(new FileReader(filepath))) {

			String sCurrentLine;
			int numberofPairsFoundInGoldSet = 0;
			int totalNumberOfPairsGreaterThanThreshold = 0;
			while ((sCurrentLine = br.readLine()) != null) {

				String[] line = sCurrentLine.split(Constants.separatorSpace);
				if (Double.parseDouble(line[2]) < Constants.precisionRecallThreshold)
					break;

				totalNumberOfPairsGreaterThanThreshold++;
				for (int i = 0; i < goldSet.size(); i++) {
					if (line[0].equals(goldSet.get(i).getPart1())
							&& line[1].equals(goldSet.get(i).getPart2())) {
						numberofPairsFoundInGoldSet++;
					}
				}
			}
			System.out.println("numberofPairsFoundInGoldSet: "
					+ numberofPairsFoundInGoldSet);
			System.out.println("totalNumberOfPairsGreaterThanThreshold:"
					+ totalNumberOfPairsGreaterThanThreshold);
			System.out.println("goldSetSize:" + goldSet.size() + "\n\n\n");

			this.precision = precision((float) numberofPairsFoundInGoldSet,
					(float) totalNumberOfPairsGreaterThanThreshold);
			this.recall = recall((float) numberofPairsFoundInGoldSet,
					(float) goldSet.size());
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public static float precision(float numberofPairsFoundInGoldSet,
			float totalNumberOfPairs) {
		return numberofPairsFoundInGoldSet / totalNumberOfPairs;
	}

	public static float recall(float numberofPairsFoundInGoldSet,
			float nuberOfPairsInGoldSet) {
		return numberofPairsFoundInGoldSet / nuberOfPairsInGoldSet;
	}

	public float Fmeasure() {
		return 2 * ((this.precision * this.recall) / (this.precision + this.recall));
	}

	public void PrecisionRecalleInFile(String functionPath, BufferedWriter out) {

		try {

			out.write(functionPath + ":\t\t");
			out.write("Precision:\t" + this.precision + "\t\tRecall:\t"
					+ this.recall + "\t\tF-measure:\t" + Fmeasure() + "\n\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static BufferedWriter createFileForPrecisionRecall(String path) {
		FileWriter fstream;
		BufferedWriter out = null;
		try {
			fstream = new FileWriter(path);
			out = new BufferedWriter(fstream);
			out.write("-------\t\tThreshold = "
					+ Constants.precisionRecallThreshold + "\t\t-------\n\n");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return out;
	}

	public static void main(String[] args) throws Exception {

		BufferedWriter out = createFileForPrecisionRecall(Constants.projectDirectory
				+ "PrecisionRecallResults "
				+ Constants.precisionRecallThreshold + ".txt");

		try (BufferedReader br1 = new BufferedReader(new FileReader(
				Constants.fileWithGoldSetPaths))) {

			String line;
			int tmp = 0;
			while ((line = br1.readLine()) != null) {
				if (tmp == 0) {
					tmp++;
					continue;
				}
				goldSet = new ArrayList<GoldSetPairs>();

				PrecisionRecall precisionRecall = new PrecisionRecall();

				String[] lineColumns = line.split(Constants.separatorSpace);

				String pathForGoldSet = Constants.projectDirectory
						+ lineColumns[0] + "/" + lineColumns[1] + "/"
						+ "GoldSet.txt";

				String pathForFunction = Constants.projectDirectory
						+ lineColumns[0] + "/" + lineColumns[1] + "/";

				String pathForSortedPairs = pathForFunction
						+ "totalPairsSorted.txt";

				System.out.println(pathForFunction);

				precisionRecall.parseGoldSetFile(pathForGoldSet);

				for (GoldSetPairs pair : goldSet) {
					System.out.println("---" + pair.getPart1() + "---"+pair.getPart2());
				}

				 precisionRecall.parseResultsFile(pathForSortedPairs);
				
				 precisionRecall.PrecisionRecalleInFile(pathForFunction,out);

			}// while

		}// try

		out.close();

	}

}
